var pkg = require('./package.json');
var path = require('path');
var webpack = require('webpack');
var BannerPlugin = webpack['BannerPlugin'];
var HtmlPlugin = require('html-webpack-plugin');
var CopyPlugin = require('copy-webpack-plugin');
var CleanPlugin = require('clean-webpack-plugin');
var MinifyPlugin = require("babel-minify-webpack-plugin");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

function getTopPath(subPath) {
  return path.join(__dirname, subPath);
}

var SRC_DIR = getTopPath('src');
var DIST_DIR = getTopPath('dist');
var MODULES_DIR = getTopPath('node_modules');
var CONTENT_DIR = getTopPath('content');
var TEMPLATE_DIR = getTopPath('template');

function getSrcPath(subPath) {
  return path.join(SRC_DIR, subPath);
}

var STYLES_DIR = getSrcPath('styles');

var devtool, plugins = [], isDev = process.env.NODE_ENV !== 'production';

plugins.push(new HtmlPlugin({
  inject: false,
  isDev: isDev,
  title: pkg.name,
  filename: 'index.html',
  template: path.join(TEMPLATE_DIR, 'index.html'),
  minify: {
    collapseInlineTagWhitespace: !isDev,
    collapseWhitespace: !isDev
  }
}));

var extractGlobalCSS = new ExtractTextPlugin({
  filename: 'global.css',
  disable: isDev
});
var extractCustomCSS = new ExtractTextPlugin({
  filename: 'custom.css',
  disable: isDev
});

plugins.push(extractGlobalCSS, extractCustomCSS);

if (isDev) {
  plugins.push(new CopyPlugin([
    {from: path.join(MODULES_DIR, '/immutable/dist/immutable.js'), to: 'js/immutable.js'},
    {from: path.join(MODULES_DIR, 'react/umd/react.development.js'), to: 'js/react.js'},
    {from: path.join(MODULES_DIR, 'react-dom/umd/react-dom.development.js'), to: 'js/react-dom.js'}
  ]));
  devtool = 'cheap-module-source-map';
} else {
  plugins.push(new CleanPlugin('dist/*', {verbose: false}));
  plugins.push(new CopyPlugin([
    {from: path.join(CONTENT_DIR)},
    {from: path.join(MODULES_DIR, 'immutable/dist/immutable.min.js'), to: 'js/immutable.js'},
    {from: path.join(MODULES_DIR, 'react/umd/react.production.min.js'), to: 'js/react.js'},
    {from: path.join(MODULES_DIR, 'react-dom/umd/react-dom.production.min.js'), to: 'js/react-dom.js'}
  ]));
  plugins.push(new MinifyPlugin({}, {comments: false}));
  plugins.push(new BannerPlugin({
    banner: [
      '/**',
      ' * Copyright (c) 2014-present, ' + pkg.author,
      ' *',
      ' * ' + pkg.name + ' - [file]',
      ' *',
      ' * description - ' + pkg.description,
      ' * version - v' + pkg.version,
      ' * compiled - ' + new Date().toISOString(),
      ' */'
    ].join('\n'),
    raw: true
  }));
}

function getLoader() {
  var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'css';
  var useCSSModules = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  var cssLoader = {
    loader: 'css-loader',
    options: {
      minimize: !isDev,
      sourceMap: isDev,
      discardComments: {
        removeAll: true
      }
    }
  };
  useCSSModules && Object.assign(cssLoader.options, {
    modules: true,
    importLoaders: 1,
    localIdentName: isDev ? '[path][local]' : 'style-[hash:8]'
  });
  var lessLoader = {
    loader: 'less-loader',
    options: {
      sourceMap: isDev
    }
  };
  var use = [];
  switch (type) {
    case 'css':
      use.push(cssLoader);
      break;
    case 'less':
      use.push(cssLoader, lessLoader);
      break;
    default:
      break;
  }
  var extracter = useCSSModules ? extractCustomCSS : extractGlobalCSS;
  return extracter.extract({
    fallback: 'style-loader',
    use: use
  });
}

module.exports = {
  context: SRC_DIR,
  entry: {
    app: getSrcPath('app.jsx')
  },
  output: {
    path: DIST_DIR,
    filename: 'js/bundle.js',
    chunkFilename: 'js/[name].bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        include: SRC_DIR,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /\.css$/,
        include: STYLES_DIR,
        use: getLoader('css')
      },
      {
        test: /\.less$/,
        include: STYLES_DIR,
        use: getLoader('less')
      },
      {
        test: /\.css$/,
        exclude: STYLES_DIR,
        use: getLoader('css', true)
      },
      {
        test: /\.less$/,
        exclude: STYLES_DIR,
        use: getLoader('less', true)
      },
      {
        test: /\.(png|jpg|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[hash:16].[ext]',
              publicPath: '',
              outputPath: 'img/'
            }
          }
        ]
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    alias: {
      components: getSrcPath('components'),
      helpers: getSrcPath('helpers'),
      images: getSrcPath('images'),
      modules: getSrcPath('modules'),
      objects: getSrcPath('objects'),
      pages: getSrcPath('pages'),
      styles: getSrcPath('styles')
    }
  },
  externals: {
    'immutable': 'Immutable',
    'react': 'React',
    'react-dom': 'ReactDOM'
  },
  plugins: plugins,
  devtool: devtool,
  stats: {
    modules: false,
    children: false
  },
  devServer: {
    stats: {
      modules: false,
      children: false
    },
    contentBase: CONTENT_DIR,
    host: '0.0.0.0',
    port: 9090
  }
};
